/**
 * 变形动画的本质是网格对象的顶点数据，从一组变为另一组
 */
import * as THREE from '../../build/three.module.js';

const scene = new THREE.Scene();

/**
 * 创建几何体，并设置变形目标
 */
const geo = new THREE.BoxGeometry(50, 50, 50);
// 变形目标数据
const box1 = new THREE.BoxGeometry(100, 5, 100);
const box2 = new THREE.BoxGeometry(5, 200, 5);
// 设置变形目标数据
geo.morphTargets[0] = { name: 'target1', vertices: box1.vertices };
geo.morphTargets[1] = { name: 'target2', vertices: box2.vertices };
// 缓冲几何体
const bugGeo = new THREE.BufferGeometry();
bugGeo.fromGeometry(geo);

const mat = new THREE.MeshLambertMaterial({
  color: 0x0000ff,
  morphTargets: true // 允许变形
});
const mesh = new THREE.Mesh(bugGeo, mat);
scene.add(mesh);

// 启用变形目标，并设置影响权重，会改变模型形状，利用这一特性，使用关键帧动画就可以驱动形变动画
// mesh.morphTargetInfluences[0] = .5;
// mesh.morphTargetInfluences[1] = 1;

/**
 * 设置关键帧数据
 */
// 一、创建关键帧轨道和动画剪辑对象
const track1 = new THREE.KeyframeTrack('.morphTargetInfluences[0]', [0, 10, 20], [0, 1, 0]);
const track2 = new THREE.KeyframeTrack('.morphTargetInfluences[1]', [20, 30, 40], [0, 1, 0]);
const clip = new THREE.AnimationClip('default', 40, [track1, track2]);

// 二、通过动画混合器创建动画播放器，控制帧动画播放
const mixer = new THREE.AnimationMixer(mesh);
const action = mixer.clipAction(clip);
action.timeScale = 5; // 调节播放速度
// action.loop = THREE.LoopOnce; // 不循环
// action.clampWhenFinished = true; // 停留在一次播放的最后一帧
action.play();

const k = innerWidth / innerHeight,
      s = 75,
      camera = new THREE.PerspectiveCamera(s, k, 1, 1000);
camera.position.set(100, 100, 100);
camera.lookAt(scene.position);

const al = new THREE.AmbientLight(0x444444);
scene.add(al);

const dl = new THREE.DirectionalLight(0xffffff, .8);
dl.position.set(100, 50, 75);
dl.target = mesh;
scene.add(dl);

const axesH = new THREE.AxesHelper(100);
scene.add(axesH);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
renderer.setClearColor(0xaaaaaa);
document.body.appendChild(renderer.domElement);

const clock = new THREE.Clock();
(function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);

  mixer.update(clock.getDelta());
})();